package com.tdd.wx.users.impl;

import com.tdd.wx.users.config.DefaultWxUserConfig;
import com.tdd.wx.users.entity.WxUser;
import com.tdd.wx.users.feignclient.VillageGiveOutBagService;
import com.tdd.wx.users.mongo.WxUserHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.validation.constraints.NotNull;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @author lobyliang
 */

@Service
@Slf4j
public class WxUserServiceServer implements com.tdd.wx.users.api.IWxUserService
{
    @Autowired
    WxUserHandler wxUserHandler;

    @Autowired
    DefaultWxUserConfig defaultUser;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    VillageGiveOutBagService bagService;

    @Override
    public WxUser getDefaultUser(WxUser wxUser)
    {
        return defaultUser.getDefaultUser(wxUser);
    }

    @Override
    public List<WxUser> findAll(int pageSize, int pageNo, WxUser example, Integer order)
    {
        Page<WxUser> all = wxUserHandler.findAll(pageSize, pageNo, example, order);
        return all.toList();
    }

    @Override
    public boolean isWxUserExist(String open_id)
    {
        return wxUserHandler.findByOpenId(open_id) != null;
    }

    @Override
    public WxUser findBySystemUserId(Long user_id)
    {
        WxUser user = new WxUser();
        user.setSysUserId(user_id);
        return wxUserHandler.findOneByExample(user);
    }

    @Override
    public WxUser findByOpenId(@NotNull String open_id)
    {
        return wxUserHandler.findByOpenId(open_id);
    }

    @Override
    public WxUser findByUnionId(String union_id)
    {
        WxUser user = new WxUser();
        user.setUnionId(union_id);
        return wxUserHandler.findOneByExample(user);
    }

    @Override
    public List<WxUser> findByShareUnionId(String union_id)
    {
        WxUser user = new WxUser();
        user.setUnionId(union_id);
        return wxUserHandler.findByExample(user);
    }

    @Override
    public List<WxUser> findByOrigin(int origin)
    {
        WxUser user = new WxUser();
        user.setOrgin(origin);
        return wxUserHandler.findByExample(user);
    }

    @Override
    public Integer increasePoints(String unionId, Integer point)
    {
        WxUser wxUser = wxUserHandler.findByUnionId(unionId);//.findByOpenId(open_id);
        if(!ObjectUtils.isEmpty(wxUser))
        {
            wxUser.increasePoint(point);
            wxUserHandler.update(wxUser);
        }
        return wxUser.getUserPoints();
    }

    @Override
    public Integer consumePoints(String unionId, Integer point)
    {
        WxUser wxUser = wxUserHandler.findByUnionId(unionId);//.findByOpenId(open_id);
        if(!ObjectUtils.isEmpty(wxUser))
        {
            wxUser.consumePoints(point);
            wxUserHandler.update(wxUser);
        }
        return wxUser.getUserPoints();
    }

    @Override
    public Integer userUpgrade(String unionId, Integer plusLevel)
    {
        WxUser wxUser = wxUserHandler.findByUnionId(unionId);///.findByOpenId(open_id);
        if(!ObjectUtils.isEmpty(wxUser))
        {
            wxUser.upgradeLevel(plusLevel);
            wxUserHandler.update(wxUser);
            return wxUser.getUserLevel();
        }
        return -1;
    }

    @Override
    public void save(@NotNull WxUser user)
    {
        user.setCreateDate(LocalDateTime.now());
        wxUserHandler.save(user);
    }

    @Override
    public void update(@NotNull WxUser user)
    {
        user.setUpdateDate(LocalDateTime.now());
        wxUserHandler.update(user);
    }

    @Override
    public void delByOpenId(String open_id)
    {
        wxUserHandler.delById(open_id);
    }

    @Override
    public WxUser newFindByUnionId(String unionId)
    {
        Query query = new Query();
        query.addCriteria(Criteria.where("unionId").is(unionId));
        return mongoTemplate.findOne(query, WxUser.class);
    }

    @Override
    public void updateWxUser(WxUser wxUser)
    {
        Query query = new Query(Criteria.where("openId").is(wxUser.getOpenId()));
        Update update = new Update().set("sysUserId", wxUser.getSysUserId());
        mongoTemplate.updateFirst(query, update, WxUser.class);
    }

    @Override
    public int getUserBagLeft(String unionId,String admCode)
    {
        if(unionId == null)
        {
            log.error("未登录用户请求可取袋子数量");
            return 0;
        }
        float defaultAmount = 1.0f;
        if(admCode!=null){
            try{
                defaultAmount = bagService.getVillageDefaultBagGiveOutAmount(admCode);
            }catch(Exception e){
                log.error("获取小区默认出袋数量失败，使用默认值1" + e.getLocalizedMessage(), e);
            }
        }
        WxUser user = wxUserHandler.findByUnionId(unionId);//.findByOpenId(openId);
        if(user==null)
        {
            log.debug("未找到微信用户：{}",unionId);
            return 0;
//            throw new Exception("未找到OpenId为:"+openId+"的用户");
        }
        log.debug("找到微信用户：{}",user);
        LocalDate lastGetBagDate = user.getLastGetBagDate();
        Integer receiveBagAmount = user.getReceiveBagAmount();

        /**
         *
         *  如果取袋时间为不为空
         *  and 如果是今天
         */
        if(lastGetBagDate != null && isToday(lastGetBagDate))
        {
            /**
             * 如果已经取了的袋子数量大于 默认的袋子数量
             */
            if(receiveBagAmount >= defaultAmount)
            {
                return 0;
            } else
            {
                int v = (int) (defaultAmount - receiveBagAmount);
                return v;
            }
        } else
        {
            /***
             * 如果不是今天，且可领取的袋子数量 大于1,
             */
            if(defaultAmount >= 1.0)
            {
                return (int) defaultAmount;
            } else
            {
                /***
                 * 可取袋子数量小于0，则表示n天可领取一个
                 */
                if(lastGetBagDate != null)
                {
                    int days = LocalDate.now().getDayOfYear() - lastGetBagDate.getDayOfYear();
                    int v = (int) (defaultAmount * days);
                    return v;
                } else
                {
                    /***
                     * 没有取过袋子，给1个
                     */
                    return 1;
                }
            }
        }
    }

    @Override
    public void updateReceiveBagAmount (String unionId,int amount)
    {
        WxUser user = wxUserHandler.findByUnionId(unionId);
        user.setReceiveBagAmount(amount);
        user.setLastGetBagDate(LocalDate.now());
        user.increasePoint(amount);//todo 看看会不会重复记录积分
        wxUserHandler.update(user);
    }


    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    private boolean isToday(LocalDate day1)
    {
        LocalDate day2 = LocalDate.now();
        return formatter.format(day1).equals(formatter.format(day2));
    }
}
